package cn.antblog.encryption;

import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.security.Key;

/**
 * @author YangJingyi
 * @date 2021-05-19 15:40
 * 3DES 算法的 加密解密
 * 3DES加密配置=desede/CBC/PKCS5Padding
 * 输出是 Base64
 * http://tool.chacuo.net/crypt3des
 */
public class ThreeDES {

    // 密钥
    private final static String secretKey = "jBnfgGCNqpXvE6OrxwXKV9F3lnm2BocK";
    // 向量
    private final static String iv = "35236018";
    // 加解密统一使用的编码方式
    private final static String encoding = "utf-8";

    /**
     * 3DES加密
     *
     * @param plainText 普通文本
     * @return
     * @throws Exception
     */
    public static String encode(String plainText) {
        Key deskey = null;
        try {
            DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());
            SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
            deskey = keyfactory.generateSecret(spec);

            Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
            IvParameterSpec ips = new IvParameterSpec(iv.getBytes());
            cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);
            byte[] encryptData = cipher.doFinal(plainText.getBytes(encoding));
            return Base64.encode(encryptData);
        } catch (Exception e) {
            e.printStackTrace();
            return plainText;
        }
    }

    /**
     * 3DES解密
     *
     * @param encryptText 加密文本
     * @return
     * @throws Exception
     */
    public static String decode(String encryptText) {
        Key deskey = null;
        try {
            DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());
            SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
            deskey = keyfactory.generateSecret(spec);
            Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
            IvParameterSpec ips = new IvParameterSpec(iv.getBytes());
            cipher.init(Cipher.DECRYPT_MODE, deskey, ips);

            byte[] decryptData = cipher.doFinal(Base64.decode(encryptText));
            return new String(decryptData, encoding);
        } catch (Exception e) {
            e.printStackTrace();
            return encryptText;
        }
    }

    public static void main(String[] args) {
        try {
            //String encode = encode("wodata|20201101120100");
            //System.out.println(encode);
            System.out.println(decode("EmDXIIiUkn8vNV/ZqfDoz14+tYEm0aUN"));
                                            //    EmDXIIiUkn8vNV/ZqfDoz14%2BtYEm0aUN    EmDXIIiUkn/N/pO0YaEBKQeuTWYXk1LI
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
